package Domain.MySqlAccessors;

import Domain.*;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;

import Persistance.MySqlUtilityManagment;
import Persistance.PrintfFormat;
import BusinessLogic.Exceptions.DataAlreadyExistException;

public class MySqlUserProxy extends MySqlProxy<User> {

    private MySqlUserActorProxy m_userActor;
    private MySqlUserGenreProxy m_userGenre;
    private MySqlActorProxy m_actors;
    private MySqlGenreProxy m_genres;
    
    public MySqlUserProxy(MySqlUtilityManagment sql) {
        super(sql);
        TABLE_NAME = "users";
        KEY_COLUMN_NAME = "name='%s'";
        ALL_COLUMN_NAMES = "name, firstname, lastname, password, vip, email, acl";

        m_userActor = new MySqlUserActorProxy(sql);
        m_userGenre = new MySqlUserGenreProxy(sql);
        m_actors = new MySqlActorProxy(sql);
        m_genres = new MySqlGenreProxy(sql);
    }

    public void addRecord(User u) throws DataAlreadyExistException {
        super.addRecord(u);

        for (Actor actor : u.getFavActors())
            m_userActor.addRecord(new UserActor(u.getUsername(),actor.getId()));
        for (Genre genre : u.getFavGenres())
            m_userGenre.addRecord(new UserGenre(u.getUsername(),genre.getId()));
    }

    public User getRecord(String key) {
        User u = super.getRecord(key);
        if (u==null)
            return null;
        
        Collection<UserActor> actors = m_userActor.searchRecords("username='"+u.getUsername()+"'");
        for (UserActor mg : actors)
            u.addActor(m_actors.getRecord(String.valueOf(mg.actor)));

        Collection<UserGenre> genres = m_userGenre.searchRecords("username='"+u.getUsername()+"'");
        for (UserGenre mg : genres)
            u.addGenre(m_genres.getRecord(String.valueOf(mg.genre)));

        return u;
    }

    public User toRecordType(ResultSet rs) throws SQLException {
        String name = (String) rs.getObject("name");
        String firstname = (String) rs.getObject("firstname");
        String lastname = (String) rs.getObject("lastname");
        String password = (String) rs.getObject("password");
        boolean vip = (Boolean) rs.getObject("vip");
        String email = (String) rs.getObject("email");
        String acl = (String) rs.getObject("acl");
        return new User(name,firstname,lastname,password,vip,email,acl);
    }

    public String toValues(User u) {
        Object[] values = {u.getUsername(),u.getFirstname(),u.getLastname(),
                u.getEncryptedPassword(),u.isVIP(),u.getEmail(),u.getACL()};
        return new PrintfFormat("'%s','%s','%s','%s',%s,'%s','%s'").sprintf(values);
    }

    public Collection<String> getUserNames() {        
        return m_sql.searchData(TABLE_NAME,"name",null);
    }

    public String[] searchUsers(String keyword, SearchUserMethods method, int start, int amount, String startWith) {
        logger.debug("Searching user by "+method+ ", keyword="+keyword);
        String filterPrefix = "";
        if (startWith!=null && !startWith.equals(""))
            filterPrefix = "name LIKE '"+startWith+"%'";
        String filter;

        switch(method) {
            case ALL:
                return m_sql.searchData(TABLE_NAME,"name",filterPrefix,start,amount);
            default:
                filter = composeLogicalExpression(filterPrefix,method.getName()+"='"+keyword+"'");
                return m_sql.searchData(TABLE_NAME,"name",filter,start,amount);
        }
    }

    private String composeLogicalExpression(String logical1,String logical2) {
        if (logical1 == null || logical1.equals(""))
            return logical2;
        if (logical2 == null || logical2.equals(""))
            return logical1;
        return logical1+" AND "+logical2;
    }
    
    /**
     * Accessors to the userFavActors table.
     */
    class MySqlUserActorProxy extends MySqlProxy<UserActor>{

        public MySqlUserActorProxy(MySqlUtilityManagment sql) {
            super(sql);
            TABLE_NAME = "userFavActors";
            KEY_COLUMN_NAME = "username='%s' AND actorId=%s";
            ALL_COLUMN_NAMES = "username, actorId";
        }

        public UserActor toRecordType(ResultSet rs) throws SQLException{
            String username = (String) rs.getObject("username");
            long actor = (Long) rs.getObject("actorId");
            return new UserActor(username,actor);
        }

        public String toValues(UserActor ma) {
            Object[] values = {ma.user,ma.actor};
            return new PrintfFormat("'%s',%s").sprintf(values);
        }
    }

    /**
     * Accessors to the userFavGenres table.
     */
    class MySqlUserGenreProxy extends MySqlProxy<UserGenre> {

        public MySqlUserGenreProxy(MySqlUtilityManagment sql) {
            super(sql);
            TABLE_NAME = "userFavGenres";
            KEY_COLUMN_NAME = "username='%s' AND genreId=%s";
            ALL_COLUMN_NAMES = "username, genreId";
        }

        public UserGenre toRecordType(ResultSet rs) throws SQLException{
            String username = (String) rs.getObject("username");
            long genre = (Long) rs.getObject("genreId");
            return new UserGenre(username,genre);
        }

        public String toValues(UserGenre mg) {
            Object[] values = {mg.user,mg.genre};
            return new PrintfFormat("'%s',%s").sprintf(values);
        }
    }

    class UserActor {
        public String user;
        public long actor;

        public UserActor(String name, long id) {
            user = name;
            actor = id;
        }
    }

    class UserGenre {
        public String user;
        public long genre;

        public UserGenre(String name, long id) {
            user = name;
            genre = id;
        }
    }
}
